package cn.edu.tju.ldj.cashup.task;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;

import cn.edu.tju.ldj.cashup.constant.Constant;
import cn.edu.tju.ldj.cashup.webfetcher.CCBFetcherImpl;
import cn.edu.tju.ldj.cashup.webfetcher.ICCBFetcher;
import cn.edu.tju.ldj.cashup.mailer.Mailer;

public class Ruser {
	
	private static Logger logger;
	
	static {
		logger = Logger.getLogger(Ruser.class.getName());
	}
	
	public static boolean isDebug = false;
	public static boolean isRefreshData = false;
	public static ICCBFetcher fetcher = new CCBFetcherImpl();
	public static List<Map<String, Object>> silverList = new ArrayList<Map<String,Object>>();
	public static List<Map<String, Object>> goldenList = new ArrayList<Map<String,Object>>();
	public static List<Map<String, Object>> platinList = new ArrayList<Map<String,Object>>();
	public static Double silverNewPrice = 0.0;
	public static Double goldenNewPrice = 0.0;
	public static Double platinNewPrice = 0.0; 
	
	private static int observeDateNum = 21;
	private static int fiveTenIndex = 365;
	private static int fiveTwnIndex = 365;
	private static int tenTwnIndex = 365;
	@SuppressWarnings("unused")
	private static final int STAT_INIT = -1, STAT_RISE = 0, STAT_WAVE = 1, STAT_FALL = 2;
	private static final int POSITION_INIT = 0, POSITION_BUY_LIT = 1, POSITION_BUY_MID = 2, 
	POSITION_BUY_HAV = 3, POSITION_SEL_LIT = -1, POSITION_SEL_MID = -2, POSITION_SEL_HAV = -3;
	private static final int WINDOW_INDEX = 8;
	@SuppressWarnings("unused")
	private static int curState = STAT_INIT;
	private static int curPosition = POSITION_INIT;
	private static int shortTermStat = STAT_INIT;
	private static int midTermStat = STAT_INIT;
	private static int longTermStat = STAT_INIT;
	
	private static int tradeHands = 0;     //开仓手数
	private static Double capital = 0.0;
	private static Double capitalShadow = 0.0;
//	private static Double rewards = 0.0;
//	private static Double leverage = 6.0;
	public static Double gapThreshold = 0.036;
	public static Double gapNDayThreshold = 0.036;
	public static List<String> orderList = new ArrayList<String>();
	/**
	 * @param args
	 */
	
	public static void initDayAvgPrices(){
		if(silverList.size() < WINDOW_INDEX || isRefreshData){
			silverList = fetcher.getDayAvgData(Constant.silverAvgUrl);
			isRefreshData = false;
		}
//		goldenList = fetcher.getDayAvgData(Constant.goldenAvgUrl);
//		platinList = fetcher.getDayAvgData(Constant.platinAvgUrl);
	}
	
	public static boolean getNewPrices(){
//		silverNewPrice = (Double)silverList.get(silverList.size()-1).get("close"); //for test
		logger.info("-+-+-+-+当前日期："+silverList.get(silverList.size()-1).get("time"));
		if(!isDebug){
			silverNewPrice = fetcher.getNewPrice(Constant.silverNewPriceUrl);
			if(silverNewPrice > 0.1){
				return true;
			}else{
				logger.info("当前价格为0，休市中。。。");
			}
		}
		return false;
//		goldenNewPrice = fetcher.getNewPrice(Constant.goldenNewPriceUrl);
//		platinNewPrice = fetcher.getNewPrice(Constant.platinNewPriceUrl);
	}
	
	public static void getStrategy(){
		initDayAvgPrices();
		initBehaviors();
		orderList.clear();
		if(!getNewPrices()){
			if(!isDebug){
				return;
			}
		}
		getAvglineState();
		getWhereWeAre();
		informBoss();
		refreshBehaviors();
	}
	
	public static void getAvglineState(){
		int flag = 0;
		int dice = 0;
		for (int i = silverList.size()-1; i > (silverList.size() - observeDateNum - 1) && i > 0 ; i--) {
			if((Double)silverList.get(i).get("TWENDAYAVG") - (Double)silverList.get(i).get("TENDAYAVG") > 0){
				dice = 1;
			}else{
				dice = -1;
			}
			if(flag == 0){
				flag = dice;
				tenTwnIndex = 1;
			}else if(flag == dice){
				++tenTwnIndex;
			}else if(flag != dice){
				--tenTwnIndex;
//				System.out.println(silverList.get(i+1).get("time") + "  tenTwnIndex="+tenTwnIndex + " lastItem="+(silverList.size()-1) + " i="+i);
				break;
			}
		}
		if (flag == 1) {
			longTermStat = STAT_FALL;
//			System.out.println("fall");
		} else if (flag == -1) {
			longTermStat = STAT_RISE;
//			System.out.println("rise");
		}
		
		flag = 0;
		dice = 0;
		for (int i = silverList.size()-1; i > (silverList.size() - observeDateNum - 1) && i > 0 ; i--) {
			if((Double)silverList.get(i).get("TWENDAYAVG") - (Double)silverList.get(i).get("FIVEDAYAVG") > 0){
				dice = 1;
			}else{
				dice = -1;
			}
			if(flag == 0){
				flag = dice;
				fiveTwnIndex = 1;
			}else if(flag == dice){
				++fiveTwnIndex;
			}else if(flag != dice){
				--fiveTwnIndex;
//				System.out.println(silverList.get(i+1).get("time") + "  fiveTwnIndex="+fiveTwnIndex + " lastItem="+(silverList.size()-1) + " i="+i);
				break;
			}
		}
		if (flag == 1) {
			midTermStat = STAT_FALL;
//			System.out.println("fall");
		} else if (flag == -1) {
			midTermStat = STAT_RISE;
//			System.out.println("rise");
		}
		
		flag = 0;
		dice = 0;
		for (int i = silverList.size()-1; i > (silverList.size() - observeDateNum - 1) && i > 0 ; i--) {
			if((Double)silverList.get(i).get("TENDAYAVG") - (Double)silverList.get(i).get("FIVEDAYAVG") > 0){
				dice = 1;
			}else{
				dice = -1;
			}
			if(flag == 0){
				flag = dice;
				fiveTenIndex = 1;
			}else if(flag == dice){
				++fiveTenIndex;
			}else if(flag != dice){
				--fiveTenIndex;
//				System.out.println(silverList.get(i+1).get("time") + "  fiveTenIndex="+fiveTenIndex + " lastItem="+(silverList.size()-1) + " i="+i);
				break;
			}
		}
		if (flag == 1) {
			shortTermStat = STAT_FALL;
//			System.out.println("fall");
		} else if (flag == -1) {
			shortTermStat = STAT_RISE;
//			System.out.println("rise");
		}
	}
	
public static void getWhereWeAre(){
		
		if(longTermStat == STAT_FALL){
			if(midTermStat == STAT_FALL){//长期趋势为跌
				if(shortTermStat == STAT_FALL){ //蓝红黄  当前处于跌势 重空
					curState = STAT_FALL;
					logger.info("当前下行中当前下行中当前下行中-------------------");
					if(tenTwnIndex <= fiveTenIndex && tenTwnIndex <= fiveTwnIndex){//当前下行中
						if(tenTwnIndex <= WINDOW_INDEX/4 && isProceedGap() && isProceedGap(WINDOW_INDEX/2)){ //开空仓窗口 这里暂时不理会当前价格
							getWhatToDo(POSITION_SEL_HAV);
							logger.info("开空仓窗口 这里暂时不理会当前价格");
						}
					}else{
						if(isProceedGap() && isProceedGap(WINDOW_INDEX/2) && tenTwnIndex <= WINDOW_INDEX){//确定的开空信号，重仓
							getWhatToDo(POSITION_SEL_HAV);
							logger.info("蓝红黄, 确定的开空信号，重仓");
						}
					}
				}else if(shortTermStat == STAT_RISE){ //蓝黄红  平空仓
					if(isTwiTriUpAvgTwn() && curPosition < 0){//前三日有两日突破廿日均线，平仓
						getWhatToDo(POSITION_INIT);
						logger.info("前三日有两日突破廿日均线，平仓");
					}
				}
				
				//熔断保险
				if(isLotus()){
					getWhatToDo(POSITION_INIT);
					logger.info("出水芙蓉，平仓闪人");
				}
			}else if(midTermStat == STAT_RISE){// 黄蓝红 跌势结束信号
				if(shortTermStat == STAT_RISE){
					logger.info(isTriRise() + "---"+fiveTenIndex  + "---"+fiveTwnIndex + "---"+tenTwnIndex + "---"+curPosition);
					if(isTriRise() && fiveTenIndex < 2 && fiveTwnIndex < 2 && tenTwnIndex > WINDOW_INDEX/2){
						getWhatToDo(POSITION_INIT);
						logger.info("三日连涨，但是短期三线交叉，为短期小幅做空信号，本系统观望");
					}else if(isObveTwnAvg() && isProceedGap(WINDOW_INDEX/2)){//前两交易均日收于蓝线上方，为买入加仓信号，持轻多仓
						getWhatToDo(POSITION_INIT);
						logger.info("前两交易均日收于蓝线上方，本系统观望");
					}
				}
				
				//熔断保险
				if(isGuillotine()){
					getWhatToDo(POSITION_INIT);
					logger.info("断头铡刀，平仓闪人");
				}
			}
		}else if(longTermStat == STAT_RISE){ //长期趋势为涨
			if(midTermStat == STAT_FALL){
				if(shortTermStat == STAT_FALL){ //红蓝黄  开始下跌信号，中空
					curState = STAT_FALL;
					if(isProceedGap() && isProceedGap(WINDOW_INDEX/2) ){
						getWhatToDo(POSITION_SEL_MID);
						logger.info("红蓝黄  开始下跌信号，中空");
					}
				}
				
				//熔断保险
				if(isLotus()){
					getWhatToDo(POSITION_INIT);
					logger.info("出水芙蓉，平仓闪人");
				}
			}else if(midTermStat == STAT_RISE){// 中期涨势
				if(shortTermStat == STAT_RISE){ //黄红蓝  纯涨 重多仓
					if (!isTwiFall() && tenTwnIndex <= WINDOW_INDEX/4 && isProceedGap() && isProceedGap(WINDOW_INDEX/4)) { // 开多仓窗口
						getWhatToDo(POSITION_BUY_HAV);
						logger.info("开多仓窗口 这里暂时不理会当前价格");
					}
					if(curPosition < 0){
						getWhatToDo(POSITION_INIT);
						logger.info("上涨区间不宜开空，平仓");
					}
				}else if(shortTermStat == STAT_FALL){//红黄蓝  一般出现在上涨回调阶段，因为这种回调没有特别参考意义，所以无视
				}
				
				//熔断保险
				if(isGuillotine()){
					getWhatToDo(POSITION_INIT);
					logger.info("断头铡刀，平仓闪人");
				}
			}
		}
	}

	public static boolean isLotus(){
		double fivAvg = (Double)silverList.get(silverList.size()-1).get("FIVEDAYAVG");
		double tenAvg = (Double)silverList.get(silverList.size()-1).get("TENDAYAVG");
		double twnAvg = (Double)silverList.get(silverList.size()-1).get("TWENDAYAVG");
		double low = (Double)silverList.get(silverList.size() - 1).get("low");
		double open = (Double)silverList.get(silverList.size() - 1).get("open");
		double close = (Double)silverList.get(silverList.size() - 1).get("close");
		if((close > fivAvg && close > tenAvg && close > twnAvg) && (low < (tenAvg + twnAvg)/2)){//twnAvg
			return true;
		}else if((close - open) > open*0.036){
			return true;
		}else{
			return false;
		}
	}
	
	public static boolean isGuillotine(){
		double fivAvg = (Double)silverList.get(silverList.size()-1).get("FIVEDAYAVG");
		double tenAvg = (Double)silverList.get(silverList.size()-1).get("TENDAYAVG");
		double twnAvg = (Double)silverList.get(silverList.size()-1).get("TWENDAYAVG");
		double high = (Double)silverList.get(silverList.size() - 1).get("high");
		double open = (Double)silverList.get(silverList.size() - 1).get("open");
		double close = (Double)silverList.get(silverList.size() - 1).get("close");
		if((close < fivAvg && close < tenAvg && close < (twnAvg*0.7 + tenAvg)/1.7) && (high > (tenAvg + fivAvg)/2)){// 
			return true;
		}else if((open - close) > open*0.036){
			return true;
		}else{
			return false;
		}
	}
	
	public static boolean isProceedGap(){
		double fivAvg = (Double)silverList.get(silverList.size()-1).get("FIVEDAYAVG");
		double tenAvg = (Double)silverList.get(silverList.size()-1).get("TENDAYAVG");
		double twnAvg = (Double)silverList.get(silverList.size()-1).get("TWENDAYAVG");
		double gap = Math.abs(twnAvg - tenAvg) + Math.abs(twnAvg - fivAvg) + Math.abs(fivAvg - tenAvg);
		return gap > gapThreshold?true:false;
	}
	
	public static boolean isProceedGap(int dayNum){
		double gap = 0.0;
		for (int i = 0; i < dayNum; i++) {
			double fivAvg = (Double)silverList.get(silverList.size()-1-i).get("FIVEDAYAVG");
			double tenAvg = (Double)silverList.get(silverList.size()-1-i).get("TENDAYAVG");
			double twnAvg = (Double)silverList.get(silverList.size()-1-i).get("TWENDAYAVG");
			gap += Math.abs(twnAvg - tenAvg) + Math.abs(twnAvg - fivAvg) + Math.abs(fivAvg - tenAvg);
		}
		gap = gap/dayNum;
		return gap > gapNDayThreshold?true:false;
	}
	
	public static void initBehaviors(){
		if(Math.abs(capital) > 0.1){
			return;
		}
		try {
			String encoding = "UTF8";
			File file = new File(isDebug?"data.txt":Constant.dataTxtUrl);
			if (file.isFile() && file.exists()) { // 判断文件是否存在
				InputStreamReader read = new InputStreamReader(
						new FileInputStream(file), encoding);// 考虑到编码格式
				BufferedReader bufferedReader = new BufferedReader(read);
				String lineTxt = null;
				while ((lineTxt = bufferedReader.readLine()) != null) {
					tradeHands = Integer.valueOf(lineTxt.split("\":")[1].split(",\"")[0]);
					capital = Double.valueOf(lineTxt.split("\":")[2].split(",\"")[0]);
					capitalShadow = Double.valueOf(lineTxt.split("\":")[3].split(",\"")[0]);
					switch(tradeHands){
						case 0: curPosition = POSITION_INIT; break;
						case 1: curPosition = POSITION_BUY_LIT; break;
						case 2: curPosition = POSITION_BUY_MID; break;
						case 3: curPosition = POSITION_BUY_HAV; break;
						case -1: curPosition = POSITION_SEL_LIT; break;
						case -2: curPosition = POSITION_SEL_MID; break;
						case -3: curPosition = POSITION_SEL_HAV; break;
					}
				}
				read.close();
			} else {
				logger.info("找不到指定的文件");
			}
		} catch (Exception e) {
			logger.info("读取文件内容出错");
			e.printStackTrace();
		}
	}
	
	public static void refreshBehaviors(){
		String dataStr = "\"tradeHands\":"+tradeHands+",\"capital\":" + formatDouble(capital)+",\"capitalShadow\":" + capitalShadow;
		logger.info(dataStr);
		try {
			OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(isDebug?"data.txt":Constant.dataTxtUrl));  
			osw.write(dataStr,0, dataStr.length());
			osw.flush();
			osw.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
		
	}
	
	public static void writeFile(String filename, String outstream){
		String dataStr = outstream;
		try {
			OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filename));  
			osw.write(dataStr,0, dataStr.length());
			osw.flush();
			osw.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
		
	}
	
	public static void getWhatToDo(int position){
		if(position == curPosition){
			return;
		}
		switch(position){
			case POSITION_INIT: 
				switch(curPosition){
					case POSITION_INIT: break;
					case POSITION_BUY_HAV: selFree(POSITION_BUY_HAV); break;
					case POSITION_BUY_LIT: selFree(POSITION_BUY_LIT); break;
					case POSITION_BUY_MID: selFree(POSITION_BUY_MID); break;
					case POSITION_SEL_HAV: buyFree(POSITION_SEL_HAV); break;
					case POSITION_SEL_LIT: buyFree(POSITION_SEL_LIT); break;
					case POSITION_SEL_MID: buyFree(POSITION_SEL_MID); break;
					default: break;
				}break;
			case POSITION_BUY_HAV: 
				switch(curPosition){
				case POSITION_INIT: buyOpen(POSITION_BUY_HAV); break;
				case POSITION_BUY_HAV: break;
				case POSITION_BUY_LIT: buyOpen(POSITION_BUY_MID); break;
				case POSITION_BUY_MID: buyOpen(POSITION_BUY_LIT); break;
				case POSITION_SEL_HAV: buyFree(POSITION_SEL_HAV); buyOpen(POSITION_BUY_HAV); break;
				case POSITION_SEL_LIT: buyFree(POSITION_SEL_LIT); buyOpen(POSITION_BUY_HAV); break;
				case POSITION_SEL_MID: buyFree(POSITION_SEL_MID); buyOpen(POSITION_BUY_HAV); break;
				default: break;
			}break;
			case POSITION_BUY_LIT: 
				switch(curPosition){
				case POSITION_INIT: buyOpen(POSITION_BUY_LIT); break;
				case POSITION_BUY_HAV: selFree(POSITION_BUY_MID); break;
				case POSITION_BUY_LIT: break;
				case POSITION_BUY_MID: selFree(POSITION_BUY_LIT); break;
				case POSITION_SEL_HAV: buyFree(POSITION_SEL_HAV); buyOpen(POSITION_BUY_LIT); break;
				case POSITION_SEL_LIT: buyFree(POSITION_SEL_LIT); buyOpen(POSITION_BUY_LIT); break;
				case POSITION_SEL_MID: buyFree(POSITION_SEL_MID); buyOpen(POSITION_BUY_LIT); break;
				default: break;
			}break;
			case POSITION_BUY_MID: 
				switch(curPosition){
				case POSITION_INIT: buyOpen(POSITION_BUY_MID); break;
				case POSITION_BUY_HAV: selFree(POSITION_BUY_LIT); break;
				case POSITION_BUY_LIT: buyOpen(POSITION_BUY_LIT); break;
				case POSITION_BUY_MID: break;
				case POSITION_SEL_HAV: buyFree(POSITION_SEL_HAV); buyOpen(POSITION_BUY_MID); break;
				case POSITION_SEL_LIT: buyFree(POSITION_SEL_LIT); buyOpen(POSITION_BUY_MID); break;
				case POSITION_SEL_MID: buyFree(POSITION_SEL_MID); buyOpen(POSITION_BUY_MID); break;
				default: break;
			}break;
			case POSITION_SEL_HAV: 
				switch(curPosition){
				case POSITION_INIT: selOpen(POSITION_SEL_HAV); break;
				case POSITION_BUY_HAV: selFree(POSITION_BUY_HAV); selOpen(POSITION_SEL_HAV); break;
				case POSITION_BUY_LIT: selFree(POSITION_BUY_LIT); selOpen(POSITION_SEL_HAV); break;
				case POSITION_BUY_MID: selFree(POSITION_BUY_MID); selOpen(POSITION_SEL_HAV); break;
				case POSITION_SEL_HAV: break;
				case POSITION_SEL_LIT: selOpen(POSITION_SEL_MID); break;
				case POSITION_SEL_MID: selOpen(POSITION_SEL_LIT); break;
				default: break;
			}break;
			case POSITION_SEL_LIT: 
				switch(curPosition){
				case POSITION_INIT: selOpen(POSITION_SEL_LIT); break;
				case POSITION_BUY_HAV: selFree(POSITION_BUY_HAV); selOpen(POSITION_SEL_LIT); break;
				case POSITION_BUY_LIT: selFree(POSITION_BUY_LIT); selOpen(POSITION_SEL_LIT); break;
				case POSITION_BUY_MID: selFree(POSITION_BUY_MID); selOpen(POSITION_SEL_LIT); break;
				case POSITION_SEL_HAV: buyFree(POSITION_BUY_MID); break;
				case POSITION_SEL_LIT: break;
				case POSITION_SEL_MID: buyFree(POSITION_BUY_LIT); break;
				default: break;
			}break;
			case POSITION_SEL_MID: 
				switch(curPosition){
				case POSITION_INIT: selOpen(POSITION_SEL_MID); break;
				case POSITION_BUY_HAV: selFree(POSITION_BUY_HAV); selOpen(POSITION_SEL_MID); break;
				case POSITION_BUY_LIT: selFree(POSITION_BUY_LIT); selOpen(POSITION_SEL_MID); break;
				case POSITION_BUY_MID: selFree(POSITION_BUY_MID); selOpen(POSITION_SEL_MID); break;
				case POSITION_SEL_HAV: buyFree(POSITION_BUY_LIT); break;
				case POSITION_SEL_LIT: selOpen(POSITION_SEL_LIT); break;
				case POSITION_SEL_MID: break;
				default: break;
			}break;
			default: break;
		}
		curPosition = position;
	}
	
	public static boolean isTriRise(){//连续三日纯涨
		if(silverList.size() < 3){
			return false;
		}
			
		for (int i = 0; i < 3; i++) {
			if((Double)silverList.get(silverList.size()-1-i).get("open") - (Double)silverList.get(silverList.size()-1-i).get("close") > 0){
				return false;
			}
		}
		return true;
	}
	
	public static boolean isTwiFall(){
		if(silverList.size() < 3){
			return false;
		}
			
		for (int i = 0; i < 2; i++) {
			if((Double)silverList.get(silverList.size()-1-i).get("open") - (Double)silverList.get(silverList.size()-1-i).get("close") <= 0){
				return false;
			}
		}
		return true;
	}
	
	public static boolean isTwiTriUpAvgTwn(){//前三日有最起码两日突破廿日线，且最近一日穿插廿日线
		if(silverList.size() < 3){
			return false;
		}
		if((Double)silverList.get(silverList.size() - 1).get("high") - (Double)silverList.get(silverList.size() - 1).get("TWENDAYAVG") > 0){
			if((Double)silverList.get(silverList.size() - 2).get("high") - (Double)silverList.get(silverList.size() - 2).get("TWENDAYAVG") > 0){
				return true;
			}
			if((Double)silverList.get(silverList.size() - 3).get("high") - (Double)silverList.get(silverList.size() - 3).get("TWENDAYAVG") > 0){
				return true;
			}
		}
		return false;
	}
	
	public static boolean isObveTwnAvg(){//前两日均收于廿日线上方
		if(silverList.size() < 3){
			return false;
		}
		if((Double)silverList.get(silverList.size() - 1).get("close") - (Double)silverList.get(silverList.size() - 1).get("TWENDAYAVG") > 0
				&& (Double)silverList.get(silverList.size() - 2).get("close") - (Double)silverList.get(silverList.size() - 2).get("TWENDAYAVG") > 0){
			return true;
		}
		return false;
	}
	
	public static void buyOpen(int units){
		tradeHands += Math.abs(units);
		capital -= Math.abs(units*1000)*silverNewPrice;
		logger.info("capital---"+capital);
		String newOrder = "买入开仓："+Math.abs(units)+"手，价格："+formatDouble(silverNewPrice)+"，目前持仓"+tradeHands+"手。";
		orderList.add(newOrder);
	}
	
	public static void buyFree(int units){
		tradeHands += Math.abs(units);
		capital -= Math.abs(units*1000)*silverNewPrice;
		logger.info("capital---"+capital);
		String newOrder = "买入平仓："+Math.abs(units)+"手，价格："+formatDouble(silverNewPrice)+"，目前持仓"+tradeHands+"手。";
		if(tradeHands == 0){
			newOrder += "浮动盈亏："+ formatDouble(capital -capitalShadow);
		}
		orderList.add(newOrder);
	}
	
	public static void selOpen(int units){
		tradeHands -= Math.abs(units);
		capital += Math.abs(units*1000)*silverNewPrice;
		logger.info("capital---"+capital);
		String newOrder = "卖出开仓："+Math.abs(units)+"手，价格："+formatDouble(silverNewPrice)+"，目前持仓"+tradeHands+"手。";
		orderList.add(newOrder);
	}
	
	public static void selFree(int units){
		tradeHands -= Math.abs(units);
		capital += Math.abs(units*1000)*silverNewPrice;
		logger.info("capital---"+capital);
		String newOrder = "卖出平仓："+Math.abs(units)+"手，价格："+formatDouble(silverNewPrice)+"，目前持仓"+tradeHands+"手。";
		if(tradeHands == 0){
			newOrder += "浮动盈亏："+ formatDouble(capital -capitalShadow);
		}
		orderList.add(newOrder);
	}
	
	public static double formatDouble(Double value){
		return Math.round(value*10000)/10000.0000;
	}
	
	public static void informBoss(){
		Mailer mailer = new Mailer();
		String subject = "策略：";
		for (String content : orderList) {
			logger.info(content);
			for (String address : Constant.emailListBoss) {
				try {
					if (!isDebug) {
						mailer.sendMail(address, subject, content);
					}
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void strategyTest(){
		isDebug = true;
		tradeHands = 0;
		capital = 10000.0;
		capitalShadow = 10000.0;
		refreshBehaviors();
		initDayAvgPrices();
		List<Map<String, Object>> silverListShadow = silverList;
		Map<String, Object> fakeItem = new HashMap<String, Object>();
		fakeItem.put("time", "当前交易日");
		fakeItem.put("open",silverListShadow.get(silverListShadow.size() - 1).get("open"));
		fakeItem.put("high",silverListShadow.get(silverListShadow.size() - 1).get("high"));
		fakeItem.put("low",silverListShadow.get(silverListShadow.size() - 1).get("low"));
		fakeItem.put("close",silverListShadow.get(silverListShadow.size() - 1).get("close"));
		fakeItem.put("valueS",silverListShadow.get(silverListShadow.size() - 1).get("valueS"));
		fakeItem.put("FIVEDAYAVG",silverListShadow.get(silverListShadow.size() - 1).get("FIVEDAYAVG"));
		fakeItem.put("TENDAYAVG",silverListShadow.get(silverListShadow.size() - 1).get("TENDAYAVG"));
		fakeItem.put("TWENDAYAVG",silverListShadow.get(silverListShadow.size() - 1).get("TWENDAYAVG"));
		fakeItem.put("CURR_COD","1561");
		silverListShadow.add(fakeItem);
		
		String priceData = "{\"data\":\n\t[";
		String profitData = "{\"data\":\n\t[";
		String positionData = "{\"data\":\n\t[";
		for (int i = observeDateNum; i < silverListShadow.size(); i++) {
			if(i == silverListShadow.size() - 1){
				silverNewPrice = (Double)silverListShadow.get(i).get("close");
			}else{
				silverNewPrice = ((Double)silverListShadow.get(i+1).get("open")*0.8 + (Double)silverListShadow.get(i+1).get("close")*0.2);
				SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");//小写的mm表示的是分钟
				Date dt;
				try {
					dt = sdf.parse((String)silverListShadow.get(i+1).get("time"));
					long dtlong = dt.getTime();
					priceData += "\n\t\t[" + dtlong + "," + silverNewPrice + "],";
					profitData += "\n\t\t[" + dtlong + "," + ((capital + silverNewPrice*1000*tradeHands) == 0.0 ? 10000.0 : capital + silverNewPrice*1000*tradeHands) + "],";
					if(i == observeDateNum){
						positionData += ("\n\t\t[" + dtlong + "," + 25 + "],");
					}else{
						positionData += ("\n\t\t[" + dtlong + "," + (25 + tradeHands) + "],");
					}
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			silverList = silverListShadow.subList(0, i);
			getStrategy();
		}
		logger.debug(silverListShadow.get(silverListShadow.size()-1).get("time"));
		priceData = priceData.substring(0, priceData.length()-1);
		priceData += "\n]}";
//		System.out.println(priceData);
		writeFile(Constant.deployPath + "aapl.json", priceData);
		
		profitData = profitData.substring(0, profitData.length()-1);
		profitData += "\n]}";
//		System.out.println(profitData);
		writeFile(Constant.deployPath + "goog.json", profitData);
		
		positionData = positionData.substring(0, positionData.length()-1);
		positionData += "\n]}";
//		System.out.println(positionData);
		writeFile(Constant.deployPath + "msft.json", positionData);
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		strategyTest();
	}
}
